package cn.pugle.base;

import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by tzp on 15-8-20.
 */
public class PatternTest {
    //匹配以^ae开始，以^结束的最小子串
    private static final Pattern siteIdPattern = Pattern.compile("\\^ae=(.*?)\\^");//我的写法 v1 //用了惰性量词 *?  问题是把下一个组的^吞了
    private static final Pattern siteIdPattern1 = Pattern.compile("\\^ae=(.*?)(?=\\^|$)");//我的写法 v2 加入了零寛断言非捕获
    private static final Pattern siteIdPattern2 = Pattern.compile("\\^ae=([^^]*)");//梦林的写法  ^除了表示开头，还表示`非`

    public static void main(String[] args) {
        baseTest();
    }

    public static void matcherTest() {
        Matcher matcher = Pattern.compile("\\(.*?\\)").matcher("a(b)c(d)e");
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_");
        }
        matcher.appendTail(sb);
        System.out.println(sb.toString());
    }

    public static void baseTest() {
        String str = "ae=000^ae=111^ae=222^ae=333^ae=444";
        //我的两个写法，
        Matcher m = siteIdPattern.matcher(str);
        while (m.find()) {
            System.out.println(m.group(1));
        }
        System.out.println("--- --- 0 --- ---");

        //零寛正向断言
        Matcher m1 = siteIdPattern1.matcher(str);
        while (m1.find()) {
            System.out.println(m1.group(1));
        }
        System.out.println("--- --- 1 --- ---");

        Matcher m2 = siteIdPattern2.matcher(str);
        while (m2.find()) {
            System.out.println(m2.group(1));
        }
        System.out.println("--- --- 2 --- ---");

        //零寛匹配！！(和前面的零宽断言不是一个东西)
        Pattern p3 = Pattern.compile("e*");
        Matcher m3 = p3.matcher(str);
        while (m3.find()) {
            System.out.println("- " + m3.group());//除了输出e 还输出了一堆空串
        }
        System.out.println("--- --- 零宽匹配问题 --- ---");
        //pattern . quote
        System.out.println(Pattern.quote("^"));
        System.out.println("1^1".split(Pattern.quote("^")).length);
        System.out.println("--- --- 测试quote --- ---");
        String[] split = str.split("ae", 3);//看注释
        System.out.println(split.length);
        System.out.println(Arrays.deepToString(split));
    }


    public void replaceTest() {
        //so Pattern.quote方法是将一个字符串用\Q \E包围起来，这样在将他用于正则的pattern时直接作为字符串（不对里面的内容转义）
        String str1 = Pattern.quote("ab\\");
        System.out.println(str1);// \Qab\\E

        //转义是‘显示端’要做的事，在内存中就是那个字符。
        String str2 = "ab\\tab\"";
        System.out.println(str2);// ab\tab"

        //common lang3 StringEscapeUtile escape unescape方法
        String str3 = StringEscapeUtils.escapeJava(str2);
        System.out.println(str3);

        //string.replaceAll方法实际调用了Matcher.replaceAll方法，其中对于\ 和 $ 符需要特殊处理,see myMethod comment。
        String xx = "\\\\aaaa\"\"";
        System.out.println(xx.replaceAll("\"", "\\\\xx\""));
        //replace方法 实际上也替换了所有的匹配，但是第二个参数进行了matcher.quoteReplacement方法。
        System.out.println(xx.replace("\"", "\\\\xx\""));
    }


    private static final char SEP = '$';
    private static final char SEP1 = '#';

    public static String replacePathPlaceholder(String paramJson) {
        int cusor = 0;//输入已经处理过的边界。
        StringBuilder sb = new StringBuilder(paramJson.length() * 2);//best effort to avoid array copy
        while (cusor < paramJson.length() - 1) {
            int indexSepLeft = paramJson.indexOf(SEP, cusor);
            if (indexSepLeft != -1) {
                int indexSepRight = paramJson.indexOf(SEP, indexSepLeft + 1);
                if (indexSepRight != -1) {
                    String placeholder = paramJson.substring(indexSepLeft + 1, indexSepRight);
                    String[] split = placeholder.split(String.valueOf(SEP1), -1);
                    if (split.length == 3) {//找到了一个正确的占位符
                        sb.append(paramJson, cusor, indexSepLeft);
                        sb.append("___");
                        cusor = indexSepRight + 1;
                        continue;
                    }
                }
                throw new RuntimeException("error sep pair");
            } else {
                sb.append(paramJson, cusor, paramJson.length());
                break;
            }
        }
        return sb.toString();
    }

    public static String replaceWithSubStrings(String paramJson) {
        String[] placeholders = StringUtils.substringsBetween(paramJson, String.valueOf(SEP), String.valueOf(SEP));
        for (String placeholder : placeholders) {
            String[] split = placeholder.split(String.valueOf(SEP1), -1);
            if (split.length == 3) {//找到了一个正确的占位符
                paramJson = StringUtils.replace(paramJson, "$" + placeholder + "$", "___");
                continue;
            }
            throw new RuntimeException("error sep pair");
        }
        return paramJson;
    }

    public static Pattern placeHolderPattern = Pattern.compile("\\$(.*?)#(.*?)#(.*?)\\$");

    public static String replaceWithMatcher(String paramJson) {
        Matcher matcher = placeHolderPattern.matcher(paramJson);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "___");
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
}
